home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Dots & Pixels
/
sources
/
vretrace.cp
< prev
next >
Wrap
Text File
|
1995-09-29
|
4KB
|
150 lines
#include <Retrace.h>
#include <Devices.h>
#include <SegLoad.h>
#include <Timer.h>
#include "stopwatch.h"
#include "vretrace.h"
// #define _DEBUG_
VBLUPP vretrace::theVBLProcPtr = allocateVBL();
VBLUPP vretrace::allocateVBL( void)
{
//
// Determine size of theVBLProc
//
Handle VBL_resource = Get1Resource( 'VBL ', 128);
if( VBL_resource == 0)
{
DebugStr( "\pcould not get VBL resource. Exit immediately!");
}
theVBLProcPtr = (VBLUPP)NewRoutineDescriptor(
(ProcPtr)(*VBL_resource), uppVBLProcInfo, kM68kISA | kOld68kRTA);
return theVBLProcPtr;
}
int vretrace::start()
{
int result = -1;
if( !is_running)
{
result = (int)SlotVInstall( (QElem *)&myVBLTask, mySlot);
if( result == noErr)
{
is_running = true;
}
}
#ifdef _DEBUG_
cout << "vretrace::start() returns " << result << "\n";
#endif
return result;
}
int vretrace::stop()
{
int result = -1;
if( is_running)
{
result = (int)SlotVRemove( (QElem *)&myVBLTask, mySlot);
if( result == noErr)
{
is_running = false;
}
}
#ifdef _DEBUG_
cout << "vretrace::stop() returns " << result << "\n";
#endif
return result;
}
void vretrace::init( const short theSlot, const short how_often)
{
myVBLTask.qType = vType;
myVBLTask.vblAddr = theVBLProcPtr;
myVBLTask.vblCount = how_often;
//
// 940211:
// From IM, Phonebook edition, page 4 from the Vertical Retrace Manager chapter:
//
// VBLPhase contains an integer (smaller than vblCount) used…
//
// Possibly the _deep_ problem with 'framerate_of_main_monitor' is
// caused by the fact that I changed
//
// myVBLTask.vblPhase = how_often % 9;
// to
// myVBLTask.vblPhase = (short)this % 9; // just something
// some time ago.
//
myVBLTask.vblPhase = (short)this % how_often; // just something
the_interval = how_often;
numtimes_run = 0L;
is_running = false;
mySlot = theSlot;
}
unsigned long vretrace::reset( const unsigned long new_value)
{
const unsigned long result = numtimes_run;
numtimes_run = new_value;
return result;
}
unsigned long vretrace::sync( const unsigned long count)
{
const unsigned long goal = numtimes_run + count;
sync_till( goal);
return goal;
}
void vretrace::sync_till( const unsigned long goal)
{
//
// Note: we do not do
//
// while( (numtimes_run != goal)){};
//
// since we just might possible miss a tick (I can't see how, but one
// never knows (e.g. on a PowerBook going to sleep or something like that)
//
if( numtimes_run > goal)
{
//
// going to pass through zero (this doesn't happen very often ;-),
// but we do check for it, anyway. 940823: we suddenly enter this loop
// when we don't want to enter it. This is caused by the passing of
// a negative number to 'sync' (FormExp issues a 2 second early warning
// even if interstimulus time is less than 2 seconds. This results in a
// negative amount of time between the end of an experiment and the
// subsequent early warning) => This looks cool, again.
//
while( numtimes_run > goal){};
}
while( numtimes_run < goal){};
}
short vretrace::getslot( const GDHandle gDev)
{
const short refNum =(**gDev).gdRefNum; // video driver refNum for this GDevice
return (**(AuxDCEHandle)GetDCtlEntry( refNum)).dCtlSlot; // slot in which this video card sits
}
double monitor_framerate( GDHandle the_gDevice)
{
stopwatch omega;
vretrace flicker( the_gDevice);
flicker.start();
flicker.sync();
omega.start();
flicker.sync( 10);
const double num_micros = omega.microseconds( omega.stop());
return (10000000.0 / num_micros);
}